package com.dating.activity;

import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.dating.entities.Me;
import com.dating.libs.client.parttern.doit.OnAuthListener;
import com.dating.libs.client.parttern.doit.OnFacebookListener;
import com.dating.libs.facebook.AsyncFacebookRunner;
import com.dating.libs.facebook.DialogError;
import com.dating.libs.facebook.Facebook;
import com.dating.libs.facebook.Facebook.DialogListener;
import com.dating.libs.facebook.FacebookError;
import com.dating.libs.facebook.FbAPIsLogoutListener;
import com.dating.libs.facebook.Permission;
import com.dating.libs.facebook.SessionEvents;
import com.dating.libs.facebook.SessionStore;
import com.dating.libs.facebook.Utility;
import com.dating.libs.web.services.Credential;
import com.dating.libs.web.services.OAuthService;
import com.dating.pref.Constant;
import com.dating.pref.Function;
import com.dating.pref.Pref;

@TargetApi(8)
public class Login extends Activity implements OnClickListener{
	public static String Tag="Login";
	
	static Toast t;
	public static Handler mHandler;
	boolean isAuto=true;
	boolean cancel=false;
	
	public static Login mLogin;
	
	TextView txvCreateAccount;
	TextView txvFacebook;
	Button btnLogin;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.login);
		mLogin=this;
		mHandler = new Handler();
		t = Toast.makeText(this, "", Toast.LENGTH_SHORT);
		
		txvFacebook = (TextView) findViewById(R.id.txvFaceBook);
		txvCreateAccount = (TextView) findViewById(R.id.txvCreateAccount);
		btnLogin = (Button) findViewById(R.id.btnLogin);
		
		txvCreateAccount.setOnClickListener(this);
		txvFacebook.setOnClickListener(this);
		btnLogin.setOnClickListener(this);
		try{
		if(Pref.getAutoLogin(this))
			autoLogin(isAuto);
		}catch(NullPointerException e){
			showToast("Can not autologin. Please try again!");
		}
	}
	private void autoLogin(boolean auto) throws NullPointerException{
		//get value form Pref
		
		String _email=Dating.ME._email;		Log.e("email:login:", _email);
		String _auth=Pref.getAuth(this);	Log.e("authen:login", _auth);
		String _pass=Pref.getPassword(this);	Log.e("password:login:", _pass);
		String _usid=Pref.getUsid(this);	Log.e("usid:login:", _usid);
		Log.e("auto login", "Starting...");
		if(!_pass.equals("")){
			Log.e("auto login", Dating.ME.AUTH);
			
			((EditText)findViewById(R.id.username)).setText(_email);
			((EditText)findViewById(R.id.password)).setText(_pass);
			//read pass from prefence
			Dating.ME.AUTH=_auth;
			Dating.ME.UID=_usid;
			Dating.ME.setOnLoginListener(_lgListener);
			
			enabledUI(false);
			showDialog(Constant.DIALOG_LOADING);
			
			Dating.ME.doSYSLogin(_email, _pass);	//set password to MD5 is here!
		}
	}
	private void enabledUI(boolean enabled){
		((Button) findViewById(R.id.btnLogin)).setEnabled(enabled);
		((EditText) findViewById(R.id.password)).setEnabled(enabled);
		
		int orientation = getResources().getConfiguration().orientation; 
	    if (Configuration.ORIENTATION_LANDSCAPE == orientation) { 
	        //Do SomeThing; // Landscape
	    	
	    } else { 
	        //Do SomeThing;  // Portrait
	    } 
	}
	
	// BroastCast receiver
	BroadcastReceiver _receiver=new BroadcastReceiver(){
		@Override
		public void onReceive(Context context, Intent intent) {
			Login.this.finish();
		}
	};
	@Override
	protected void onStop() {
		super.onStop();
		unregisterReceiver(_receiver);
		isAuto=true;
	}
	@Override
	protected void onResume() {
		registerReceiver(_receiver, new IntentFilter("close_login_activity"));
		super.onResume();
	}
	// IMPORTANT for FACEBOOK!!!
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		try{
			super.onActivityResult(requestCode, resultCode, data);
	
			Utility.mFacebook.authorizeCallback(requestCode, resultCode, data);
		}catch(NullPointerException e){
			showToast(e.toString());
			e.printStackTrace();
		}
	}
	// SUPER METHOD
	public static void showToast(String text){
		if (t != null) {
			t.cancel();
		}
		t.setText(text);
		t.show();
	}
	
	public static void createDialog(int code){
		if(mLogin!=null)
			mLogin.showDialog(code);
	}
	
	public static void closeDialog(int code){
		if(mLogin!=null)
			mLogin.removeDialog(code);
	}
	public String getJson(JSONObject json, String filter) {
		
		try {
			return json.getString(filter);
		} catch (JSONException e) {
			e.printStackTrace();
			return "";
		} catch (NullPointerException e) {
			e.printStackTrace();
			return "";
		}
		
	}
	@Override
	@Deprecated
	protected Dialog onCreateDialog(int id) {
		Dialog d = new Dialog(this);
		d.setCancelable(true);
		// d.setCanceledOnTouchOutside(true);
		d.requestWindowFeature(Window.FEATURE_NO_TITLE);
		d.setContentView(R.layout.loading);
		switch (id) {
		case Constant.DIALOG_LOADING:
			d.setOnCancelListener(new DialogInterface.OnCancelListener(){
				@Override
				public void onCancel(DialogInterface dialog) {
					cancel=true;
					enabledUI(true);
				}
			});
			// d.setTitle("Loging in...");
			isAuto=false;
			cancel=false;
			d.show();
			break;

		default:
			break;
		}
		return d;
	}
	
	
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnLogin:
			final String username=((EditText)findViewById(R.id.username)).getText().toString();
			final String password=((EditText)findViewById(R.id.password)).getText().toString();
			
			Dating.ME=Me.getInstance(Dating.ME);
			Dating.ME.setOnLoginListener(_lgListener);
			
			enabledUI(false);
			showDialog(Constant.DIALOG_LOADING);
			cancel=false;
			Dating.ME.doSYSLogin(username, password);	//set password to MD5 is here!
			break;
		case R.id.txvCreateAccount:
			Dating.ME=Me.getInstance(Dating.ME);
			Dating.ME._type_account=Constant.TYPE_ACCOUNT_DATING;
			
			Login.this.startActivity(new Intent(Login.this, Register.class));
			break;
		case R.id.txvFaceBook:
			Dating.ME=Me.getInstance(Dating.ME);
			Dating.ME.setOnFacebookListener(_fbListener);
			
			Dating.ME.doFBLogin(Dating.ME, this, mHandler);
			break;
		default:
			break;
		}
	}
	// LOGIN SYSTEM METHOD
	OnAuthListener _lgListener=new OnAuthListener() {
		
		@Override
		public void onStart(String username, String password) {
			if(onRequestLogin(username,password)){
				Log.e("request Login", "true");
				if(cancel) return;
				//usercomin
				try {
					boolean value=new com.dating.libs.web.services.datingservice.DatingService().userComeIn();
					if(value){
						
						//updateFields
						Pref.setEmail(Login.this, username);
						Pref.setPassword(Login.this, password);
						//update Me
						Dating.ME._email=username;
						Dating.ME.refreshValues(true);
						Dating.ME.saveToDb(Login.this);
						
						//Login complete
						onComplete(value);
					}else{
						onError(new Exception("cannot Login. userCommin return false"));
					}
				} catch (Exception e) {
					e.printStackTrace();
					onError(e);
				}
			}else{
				Exception e=new Exception("Can not request Login. Try again!");
				onError(e);
			}
		}
		
		
		@Override
		public void onError(final Exception e) {
			Log.e("System Login", e.toString());
			removeDialog(Constant.DIALOG_LOADING);
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					enabledUI(true);
				}
			});
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					showToast(e.toString());
				}
			});
		}
		
		
		@Override
		public void onComplete(boolean success) {
			removeDialog(Constant.DIALOG_LOADING);
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					enabledUI(true);
				}
			});
			
			if(success){
				//show information
				Log.e("ME AUTH", Dating.ME.AUTH);
				Log.e("ME UID", Dating.ME.UID);
				Log.e("ME EMAIL", Dating.ME._email);
				Log.e("ME PASSWORD", Pref.getPassword(Login.this));
				
				Dating.ME._type_account=Constant.TYPE_ACCOUNT_DATING;
				
				Login.this.startActivity(new Intent(Login.this,Dating.class));
				Login.this.finish();
			}else{
				Log.e("onComplete", "Login failed!, try again!");
			}
		}
		
		@Override
		public void onCancel() {
			// write bla bla bla
		}

		@Override
		public boolean onRequestLogin(String username, String password) {
			boolean value=false;
			OAuthService auth=new OAuthService();
			Log.e("show EMAIL", username);
			Log.e("show PASS", password);
			try {
				if(cancel) return false;
				Credential credential=auth.requestCredential(username,password/*Register.toMD5(password)*/);
				Log.e("pass credential:", password);
				if(credential.getUserID(0)!=0){
					//Pref
					Pref.setAuth(Login.this, credential.getToken(""));
					Pref.setUsid(Login.this, credential.getUserID(0)+"");
					//Me
					Dating.ME.AUTH=credential.getToken("");
					Dating.ME.UID=credential.getUserID(0)+"";
					Dating.ME.credential=credential;
					value=true;
				}else{
					Dating.ME.credential=null;
					value=false;
				}
				//show info
				Log.e("show EMAIL", username);
				Log.e("show PASS", password);
				Log.e("show AUTH", Dating.ME.AUTH);
				Log.e("show UID",Dating.ME.UID);
				
			}catch(NumberFormatException e){
				e.printStackTrace();
				value=false;
			}
			catch (Exception e) {
				e.printStackTrace();
				value=false;
			}
			return value;
		}
		// Only for register
		@Override
		public boolean getCredential() {
			return false;
		}
	};
	// LOGIN FACEBOOK METHOD
	OnFacebookListener _fbListener=new OnFacebookListener() {
		
		@Override
		public boolean startLoginFB(Me me, Activity activity, Handler handler) {
			// Create the Facebook Object using the app id.
			Utility.mFacebook = new Facebook(Facebook.ID_FACE);
			// Instantiate the asynrunner object for asynchronous api calls.
			Utility.mAsyncRunner = new AsyncFacebookRunner(Utility.mFacebook);

			// restore session if one exists
			SessionStore.restore(Utility.mFacebook, Login.this);
			SessionEvents.addAuthListener(new FbAPIsAuthListener());
			SessionEvents.addLogoutListener(new FbAPIsLogoutListener());
			
			//login facebook
			authorizeFace(Utility.mFacebook);
			return false;
		}

		@Override
		public void finishLoginFB(Me me, Activity activity, Handler hander) {
			startActivity(new Intent(Login.this,Dating.class));
			Login.this.finish();
		}

		@Override
		public boolean authorizeFace(Facebook face) {
			// requestUserData();
			boolean value = false;
			if (!face.isSessionValid()) {
				if (loginFacebook(face)) {
					// requestUserData();
					value = true;
				} else {
					value = false;
				}
			} else {
				value = true;
				requestUserData();
			}
			return value;
		}

		@Override
		public boolean loginFacebook(Facebook face) {
			face.authorize(Login.this, Permission.user_permissions, new DialogListener() {

				
				public void onFacebookError(FacebookError e) {
					showToast(e.toString());
				}
				public void onError(DialogError e) {
					showToast(e.toString());
				}
				public void onComplete(Bundle values) {
//					showToast("Đăng nhập Facebook thành công!");
					requestUserData();
				}
				public void onCancel() {
				}
			});
			return true;
		}
	};
	
	/*
	 * The Callback for notifying the application when authorization succeeds or
	 * fails.
	 */
	public class FbAPIsAuthListener implements
			SessionEvents.AuthListener {

		public void onAuthSucceed() {
			requestUserData();
		}

		public void onAuthFail(String error) {
		}
	}
	/*
	 * Request user name, and picture to show on the main screen.
	 */
	
	public void requestUserData() {
		showDialog(Constant.DIALOG_LOADING);
		Bundle _params = new Bundle();
		String _add = "";
		String _lstStr=Permission.fields[Permission.fields.length-1];
		for (String _tmp : Permission.fields) {
			if (!_tmp.equals(_lstStr)) {
				_add += _tmp + ",";
			} else
				_add += _tmp;
		}
		Log.e(Tag, _add);
		// params.putString("fields", "id,name, picture");
		_params.putString("fields", _add);
		try {
			UserRequestListener _lst = new UserRequestListener();
			Log.e(Tag, Utility.mFacebook.getAccessToken());
			Utility.mAsyncRunner.request(Dating.ME.grapPath, _params, _lst);
		} catch (Exception e) {
			Log.e(Tag, e.toString());
		}
	}
	/*
	 * Callback for fetching current user's name, picture, uid.
	 */
	public class UserRequestListener extends com.dating.libs.facebook.BaseRequestListener {

		
		public void onComplete(final String response, final Object state) {
			removeDialog(Constant.DIALOG_LOADING);
			
			//Latitude-Longitude
			try{
				Dating.ME._latitude=Function.getLastGeopoint(Login.this).getLatitude()+"";
				Dating.ME._longitude=Function.getLastGeopoint(Login.this).getLongitude()+"";
			}catch(NullPointerException e){
				Dating.ME._latitude="0";
				Dating.ME._longitude="0";
			}
			
			//get response from facebook
			JSONObject _jsonObject;
			Log.e(Tag, "Json: "+response);
			try {
				_jsonObject = new JSONObject(response);
				
				Utility.userUID = Dating.ME._id_username	=	getJson(_jsonObject, "id");
				
				Dating.ME._address	=	"<locale>"+getJson(_jsonObject, "locale");
				Dating.ME._address	+=	"<link>"+getJson(_jsonObject, "link");
				Dating.ME._address	+=	"<address>"+getJson(_jsonObject, "address");
				
				Dating.ME._current_address=Dating.ME._address;
				
				Dating.ME._type_account=Constant.TYPE_ACCOUNT_FACEBOOK;
				Dating.ME._phone=Function.getPhoneNumber(Login.this);
				Dating.ME._category="me";
				
				Dating.ME.likes		=	getJson(_jsonObject, "likes");
				Log.e("Likes", Dating.ME.likes);
				Dating.ME._fullname	=	getJson(_jsonObject, "name");
				Dating.ME._email	=	getJson(_jsonObject, "email");
				Dating.ME._gender	=	getJson(_jsonObject, "gender");
				Dating.ME._nickname	=	getJson(_jsonObject,"username");
				Dating.ME._birthday	=	getJson(_jsonObject, "birthday");
				JSONObject picture=_jsonObject.getJSONObject("picture");
				JSONObject data=picture.getJSONObject("data");
				String _url=getJson(data, "url");
				String url=_url.replace("\\", "");
				Dating.ME._link_image	=	url;
				Dating.ME.relationship_status	=	getJson(_jsonObject, "relationship_status");
				Dating.ME._nickname	=	getJson(_jsonObject, "first_name")+getJson(_jsonObject, "last_name");
				
				//since first initial Me, values is not set data
				Dating.ME.refreshValues(true);
				
				mHandler.post(new Runnable() {

					public void run() {
						showToast("Welcome: " + Dating.ME._link_image+"!");
						Log.e("link image", Dating.ME._link_image);
						Dating.ME.saveToDb(Login.this);
						Dating.ME=Dating.ME.restoreFromDb(Login.this);
						//start Activity Dating Program
						Intent _confirm=new Intent(Login.this, Dating.class);
						Login.this.startActivity(_confirm);
						Login.this.finish();
					}
				});

			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}
}
